/*
 * Copyright 2010 Joshua Smith and Nelson Llewellyn
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package norse.view.freyja;

import javafx.scene.Node;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.scene.input.MouseEvent;
import norse.view.NorseView;
import norse.view.NorseViewHost;
import norse.model.NorseJfxHost;
import javafx.animation.Timeline;
import java.lang.StringBuilder;
import norse.model.NorseJfxMacAddress;
import norse.model.NorseJfxIpv4Address;
import org.jfxtras.scene.layout.MigLayout;
import javafx.scene.Group;
import org.jfxtras.scene.layout.MigNodeLayoutInfo;

/**
 * Graphical representation of a host in the Freyja user interface for NoRSe.
 */
public class FreyjaHost extends NorseViewHost {
    public var hostModel:NorseJfxHost;
    public var hostname:String;
    public var centerX:Number;
    public var centerY:Number;
    public var fill:Color;

    var selected:Boolean = false;
    // TODO maybe write once?
    public var view: NorseView;





    /**
     * Create the Freyja host node.
     */
    override protected function create () : Node {
        Circle {
            centerX: view.nextX()
            centerY: view.nextY()
            radius: 35
            fill: bind fill
            stroke: bind if (selected) Color.WHITE else Color.BLACK
            strokeWidth: 2
            onMouseEntered: function (event: MouseEvent) {
                selected = true;
                println(hostModel);
                view.selectedHost = this
            }
            onMouseExited: function (event: MouseEvent) {
                selected = false;
                view.selectedHost = FreyjaNullHost{}
            }
        }
    }

        /**
         * Get host details suitable for displaying to the user in the details
         * pane.
         */
        public override function getDetails():String {
                var macAddress:NorseJfxMacAddress;
                var ipAddresses:NorseJfxIpv4Address[];
                for (address in hostModel.addresses) {
                    if (address instanceof NorseJfxMacAddress) {
                        macAddress = address as NorseJfxMacAddress;
                    } else if (address instanceof NorseJfxIpv4Address) {
                        insert address as NorseJfxIpv4Address into ipAddresses;
                    }
                    // ignore other types of addresses
                }


                var detail = new StringBuilder();

                // MAC address
                detail.append("MAC Address: ");
                if (macAddress != null) {
                    detail.append(macAddress);
                } else {
                    detail.append("unknown");
                }
                detail.append("\n");

                // hostname(s)
                detail.append("Hostname");
                if (sizeof hostModel.hostnames > 1) {
                    detail.append("s");
                }
                detail.append(": ");
                if (sizeof hostModel.hostnames < 1) {
                    detail.append("unknown");
                    detail.append("\n");
                } else {
                    var firstHostname = true;
                    for (hostname in hostModel.hostnames) {
                        if (firstHostname != true) {
                            detail.append("           ");
                        }
                        detail.append(hostname);
                        detail.append("\n");
                        firstHostname = false;
                    }

                }

                // IP addresses
                detail.append("IP Address");
                if (sizeof ipAddresses > 1) {
                    detail.append("s");
                }
                detail.append(": ");
                if (sizeof ipAddresses < 1) {
                    detail.append("unknown");
                    detail.append("\n");
                } else {
                    var firstIpAddres = true;
                    for (ipAddress in ipAddresses) {
                        if (firstIpAddres != true) {
                            detail.append("             ");
                        }
                        detail.append(ipAddress);
                        detail.append("\n");
                        firstIpAddres = false;
                    }

                }

                // ports
                detail.append("Ports:");
                if (sizeof hostModel.ports < 1) {
                    detail.append(" ");
                    detail.append("none");
                    detail.append("\n");
                } else {
                    detail.append("\n");
                    for (port in hostModel.ports) {
                        detail.append("        ");
                        detail.append(port);
                        detail.append("\n");
                    }

                }

                return detail.toString();
        }

        /**
         * Reveal the host to the user.
         */
        public function reveal():Void {
            Timeline {
                keyFrames: [at (2s) {this.opacity => 1.0}]
            }.play();
        }

}

/**
 * Creates a host view for Norse's Freyja view and binds it to a NoRSe model
 * and provides a references to the main view from it.
 *
 * @param host model host to which to bind the view host
 * @param view main view that the view host will be a part of
 * @return Freyja view host.
 */
public function modelToView(host:NorseJfxHost, view:NorseView) : FreyjaHost {
        FreyjaHost {
                hostModel: bind host
                view: view
                hostname: host.hostnames[0]
                fill: bind if (host.up) Color.GREEN else Color.RED
                opacity: 0.0
        }
}

